package com.scalar.chiptrack.adaptor.ubicom.gtc;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.TestLot;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.InventoryLot;
import com.scalar.chiptrack.adaptor.dao.TestAdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.adaptor.dao.InventoryLotDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.ScalarException;

import java.io.File;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.GregorianCalendar;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.Locale;

import jxl.Workbook;
import jxl.Sheet;
import jxl.Cell;
import jxl.CellType;
import jxl.DateCell;

/**
 * Created by IntelliJ IDEA.
 * User: Sudhakar
 * Date: Jun 25, 2007
 * Time: 6:04:51 PM
 */
public class GTCDataParser extends JobHandler implements AdaptorConstants
{

    HashMap m_ftDataMap               = new HashMap();
    HashMap m_invDataMap                = new HashMap();
    private Logger m_parserLogger       = null;
    private String m_dataOutputDir      = null;

    public  GTCDataParser() throws ScalarException
    {
       try
        {
            m_dataOutputDir = AdaptorUtils.getDataOutputDir(VENDOR_NAME_GLOBAL_TEST, WIP_TYPE_TEST);
            AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );
            m_parserLogger = AdaptorUtils.getDataParserLogger( m_dataOutputDir, VENDOR_NAME_GLOBAL_TEST);
            TestAdaptorDAO.setLogger( m_parserLogger );
            InventoryLotDAO.setLogger( m_parserLogger );
            AdaptorUtils.setLogger(m_parserLogger);
        }
        catch ( ScalarException se)
        {
            log( "ERROR!! ERROR!! ERROR!! Could not create get the logger to log GlobalTest Data Parser activity, Exception: " + se );
            throw se;
        }
    }
    /**
     *
     * @throws Exception
     */
    public void execute() throws Exception
    {
        AdaptorUtils.printHeader(VENDOR_NAME_GLOBAL_TEST, CONSTANT_PARSER);

        File doneDestDir = new File(m_dataOutputDir + "/done");
        File wipDataoutDir = new File(m_dataOutputDir);

        File[] fileList = wipDataoutDir.listFiles();

        if ((fileList == null) || (fileList.length <= 3))
        {
            log("No file found in directory: " + wipDataoutDir);
            throw new ScalarException("No file found in directory: " + wipDataoutDir + "----\n\n");
        }

        ArrayList gtcWipList = new ArrayList();
        ArrayList successFileList = new ArrayList();
        boolean success = true;
        String fileName = null;

        //PARSING STARTS FROM HERE
        for (int i = 0; i < fileList.length; i++)
        {
            if (fileList[i].isDirectory() == true)
            {
                continue;
            }

            fileName = fileList[i].getAbsolutePath();
            try
            {
                if (fileList[i].getName() != null && fileList[i].getName().trim().startsWith(GTCPOP3Adaptor.GLOBAL_TEST_WIP_FILE))
                {
                    gtcWipList = parseGTCWipReport(fileName);
                    if (gtcWipList != null && gtcWipList.size() > 0)
                    {
                        getGTCWipDetails(gtcWipList);
                    }
                    //Add files to success list to move to /done directory
                    successFileList.add(fileList[i]);
                }
            }
            catch (Exception e)
            {
                success = false;
                log("Exception while parsing and storing file: " + fileName + "\nException: " + e);
                e.printStackTrace();
                throw e;
            }
        }

        try
        {
            if (m_ftDataMap.isEmpty() == false)
            {
                TestAdaptorDAO.saveTestLot(null, m_ftDataMap.values().iterator(), LOCATION_TYPE_FT, VENDOR_NAME_GLOBAL_TEST);
            }
            else
            {
                TestAdaptorDAO.closeTestLot(null,  LOCATION_TYPE_FT, VENDOR_NAME_GLOBAL_TEST);
            }
            m_ftDataMap.clear();
            m_ftDataMap = null;
        }
        catch (ScalarException se)
        {
            success = false;
            se.printStackTrace();
            log("ERROR!! ERROR!! ERROR!! Could not update Test Lot information into database: " + se);
            throw se;
        }

        /*Updating the FG Lot Information*/
        try
        {
            if (m_invDataMap.isEmpty() == false)
            {
                log(" Updating Finished Goods Lot Information");
                InventoryLotDAO.saveInventoryLot(null, m_invDataMap.values().iterator(), LOCATION_TYPE_FG, VENDOR_NAME_GLOBAL_TEST);
            }
            else
            {
                InventoryLotDAO.closeInventoryLot( null, LOCATION_TYPE_FG, VENDOR_NAME_GLOBAL_TEST);
            }
            m_invDataMap.clear();
            m_invDataMap = null;
        }
        catch (ScalarException se)
        {
            success = false;
            se.printStackTrace();
            log("ERROR!! ERROR!! ERROR!! Could not update Finished Goods Lot information into database: " + se);
            throw se;
        }

         // TO SEND THE NEW LOTS, NEW TRANSIT LOTS, NO PO LOTS, DISCREPANCY LOTS NOTIFICATIONS TO THE USER
        AdaptorDAO.sendAllNotifications(VENDOR_NAME_GLOBAL_TEST, true, true, true);

        // To Close the Drop Out Lots
        AdaptorDAO.closeDropOutLots(VENDOR_NAME_GLOBAL_TEST);

        int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( GTCPOP3Adaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);

        // Update Adaptor_Run_Info table
        try
        {
            if ( success == true )
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, GTCPOP3Adaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
            }
        }
        catch ( ScalarException se )
        {
            success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, GTCPOP3Adaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
            throw se;
         }
        // Move the successful files to 'done' directory
        if ( success )
        {
           AdaptorUtils.moveFilesToDone( successFileList, doneDestDir );
        }
    }
    /**
     *
     * @param args
     * @throws Exception
     */
    public static void main(String args[]) throws Exception
    {
        try
        {
            new GTCDataParser().execute();
        }
        catch (Exception e)
        {
            throw e;
        }
    }
    /**
     *
     * @param gtcWipFile
     * @return
     * @throws Exception
     */
    private ArrayList parseGTCWipReport( String gtcWipFile ) throws Exception
    {
        ArrayList wipList           = new ArrayList();
        String checkValue           = null;
        GTCWIPStatus gtcwipStatus   = null;

        if (gtcWipFile == null)
        {
            throw new ScalarException("Filename argument is null");
        }

        try
        {
            File wipStatusFile = new File( gtcWipFile );

            if ( wipStatusFile.exists() == false )
            {
                throw new ScalarException( gtcWipFile + " doesnt exist" );
            }

            log("\nFound " + wipStatusFile);
            log("\nParsing the file for Detail GlobalTest Wip Report...");
            System.out.println("\nFound " + wipStatusFile);
            System.out.println("\nParsing the file for GlobalTest Wip Report...");

            Workbook workbook = Workbook.getWorkbook(wipStatusFile);
            Sheet sheet = workbook.getSheet(0);

            Cell[] row = null;

            for (int rowCount = 1; rowCount < sheet.getRows(); rowCount++)
            {
                row = sheet.getRow(rowCount);
                checkValue = row[4].getContents().trim();

                if (checkValue != null && checkValue.trim().length() > 0)
                {
                    gtcwipStatus = new GTCWIPStatus();

                    if (row.length > 0)
                    {
                        if (row[0].getType().equals(CellType.EMPTY))
                        {
                            gtcwipStatus.setReceivedDate(null);
                        }
                        else if(row[0].getType().equals(CellType.DATE))
                        {
                            DateCell dc = (DateCell) row[0];
                            java.util.Date recDate = null;
                            recDate = dc.getDate();

                            if ("America/Los_Angeles".equals(System.getProperty("user.timezone")))
                            {
                                Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.US);
                                cal.setTime(recDate);
                                recDate = new GregorianCalendar(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE)).getTime();
                                gtcwipStatus.setReceivedDate(StringUtils.formatDateToString(recDate));
                            }
                            else
                            {
                                Calendar cal = new GregorianCalendar();
                                cal.setTime(recDate);
                                recDate = new GregorianCalendar(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE)).getTime();
                               gtcwipStatus.setReceivedDate(StringUtils.formatDateToString(recDate));
                            }
                        }
                    }
                    if (row.length > 1)
                    {
                        if (row[1].getType().equals(CellType.EMPTY))
                        {
                            gtcwipStatus.setProductDevice(null);
                        }
                        else
                        {
                            gtcwipStatus.setProductDevice(row[1].getContents().trim());
                        }
                    }
                    if (row.length > 2)
                    {
                        if (row[2].getType().equals(CellType.EMPTY))
                        {
                            gtcwipStatus.setPackageType(null);
                        }
                        else
                        {
                            gtcwipStatus.setPackageType(row[2].getContents().trim());
                        }
                    }
                    if (row.length > 3)
                    {
                        if (row[3].getType().equals(CellType.EMPTY))
                        {
                            gtcwipStatus.setDateCode(null);
                        }
                        else
                        {
                            gtcwipStatus.setDateCode(row[3].getContents().trim());
                        }
                    }
                    if (row.length > 4)
                    {
                        if (row[4].getType().equals(CellType.EMPTY))
                        {
                            gtcwipStatus.setPkgLot(null);
                        }
                        else
                        {
                            gtcwipStatus.setPkgLot(row[4].getContents().trim());
                        }
                    }
                    if (row.length > 5)
                    {
                        if (row[5].getType().equals(CellType.EMPTY))
                        {
                            gtcwipStatus.setReceivedQty(null);
                        }
                        else
                        {
                            gtcwipStatus.setReceivedQty(row[5].getContents().trim());
                        }
                    }
                    if (row.length > 6)
                    {
                        if (row[6].getType().equals(CellType.EMPTY))
                        {
                            gtcwipStatus.setCurrentQty(null);
                        }
                        else
                        {
                            gtcwipStatus.setCurrentQty(row[6].getContents().trim());
                        }
                    }
                    if (row.length > 7)
                    {
                        if (row[7].getType().equals(CellType.EMPTY))
                        {
                            gtcwipStatus.setTestQtyPass(null);
                        }
                        else
                        {
                            gtcwipStatus.setTestQtyPass(row[7].getContents().trim());
                        }
                    }
                    if (row.length > 8)
                    {
                        if (row[8].getType().equals(CellType.EMPTY))
                        {
                            gtcwipStatus.setTestQtyFail(null);
                        }
                        else
                        {
                            gtcwipStatus.setTestQtyFail(row[8].getContents().trim());
                        }
                    }
                    if (row.length > 9)
                    {
                        if (row[9].getType().equals(CellType.EMPTY))
                        {
                            gtcwipStatus.setTestCompletionDate(null);
                        }
                        else if(row[9].getType().equals(CellType.DATE))
                        {
                            DateCell dc = (DateCell) row[9];
                            java.util.Date testCompletionDate = null;
                            testCompletionDate = dc.getDate();

                            if ("America/Los_Angeles".equals(System.getProperty("user.timezone")))
                            {
                                Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.US);
                                cal.setTime(testCompletionDate);
                                testCompletionDate = new GregorianCalendar(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE)).getTime();
                               gtcwipStatus.setTestCompletionDate(StringUtils.formatDateToString(testCompletionDate));
                            }
                            else
                            {
                                Calendar cal = new GregorianCalendar();
                                cal.setTime(testCompletionDate);
                                testCompletionDate = new GregorianCalendar(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE)).getTime();
                                gtcwipStatus.setTestCompletionDate(StringUtils.formatDateToString(testCompletionDate));
                            }
                        }
                    }
                    if (row.length > 10)
                    {
                        if (row[10].getType().equals(CellType.EMPTY))
                        {
                            gtcwipStatus.setPercentYield(null);
                        }
                        else
                        {
                            gtcwipStatus.setPercentYield(row[10].getContents().trim());
                        }
                    }
                    if (row.length > 11)
                    {
                        if (row[11].getType().equals(CellType.EMPTY))
                        {
                            gtcwipStatus.setStorage(null);
                        }
                        else
                        {
                            gtcwipStatus.setStorage(row[11].getContents().trim());
                        }
                    }
                    if (row.length > 12)
                    {
                        if (row[12].getType().equals(CellType.EMPTY))
                        {
                            gtcwipStatus.setShippingDate(null);
                        }
                        else
                        {
                            gtcwipStatus.setShippingDate(row[12].getContents().trim());
                        }
                    }
                    if (row.length > 13)
                    {
                        if (row[13].getType().equals(CellType.EMPTY))
                        {
                            gtcwipStatus.setNotes(null);
                        }
                        else
                        {
                            gtcwipStatus.setNotes(row[13].getContents().trim());
                        }
                    }
                    if (row.length > 14)
                    {
                        if (row[14].getType().equals(CellType.EMPTY))
                        {
                            gtcwipStatus.setTestProgram(null);
                        }
                        else
                        {
                            gtcwipStatus.setTestProgram(row[14].getContents().trim());
                        }
                    }

                    wipList.add(gtcwipStatus);
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return wipList;
    }
    /**
     *
     * @param testWipList
     * @throws Exception
     */
    private void getGTCWipDetails( ArrayList testWipList )  throws Exception
    {
        if ( testWipList == null || testWipList.size() == 0 )
        {
           log( "No Test Lots when the List is Empty");
           return;
        }

        GTCWIPStatus gtcwipStatus   = null;
        String lotNumber            = null;
        String partNumber           = null;
        int qtyOut                  = 0;
        TestLot testLot             = null;
        InventoryLot inventoryLot   = null;

        try
        {

            Iterator iterator = testWipList.iterator();

            while (iterator.hasNext())
            {
                gtcwipStatus = (GTCWIPStatus) iterator.next();

                lotNumber = gtcwipStatus.getPkgLot();
                partNumber = gtcwipStatus.getProductDevice();

                try
                {
                    qtyOut = Integer.parseInt(gtcwipStatus.getTestQtyPass());
                }
                catch(NumberFormatException npe)
                {
                    qtyOut = 0;
                }

                if( lotNumber != null && partNumber != null )
                {
                    if (qtyOut > 0)
                    {
                        testLot = (TestLot) m_ftDataMap.get(lotNumber + partNumber);

                        if (testLot == null)
                        {
                            testLot = new TestLot();
                            m_ftDataMap.put(lotNumber + partNumber, testLot);
                        }

                        int quantityIn = 0;
                        if (testLot.getQtyIn() != null)
                        {
                            try
                            {
                                quantityIn = Integer.parseInt(testLot.getQtyIn());
                            }
                            catch (NumberFormatException npe) {
                            }
                            try
                            {
                                quantityIn += Integer.parseInt( gtcwipStatus.getCurrentQty());
                            }
                            catch (NumberFormatException npe) {
                            }
                        }
                        else
                        {
                            try
                            {
                                quantityIn = Integer.parseInt( gtcwipStatus.getCurrentQty());
                            }
                            catch (NumberFormatException npe) {
                            }
                        }

                        int quantityOut = 0;
                        if (testLot.getQtyOut() != null)
                        {
                            try
                            {
                                quantityOut = Integer.parseInt(testLot.getQtyOut());
                            }
                            catch (NumberFormatException npe) {
                            }
                            try
                            {
                                quantityOut += qtyOut;
                            }
                            catch (NumberFormatException npe) {
                            }
                        }
                        else
                        {
                            try
                            {
                                quantityOut = qtyOut;
                            }
                            catch (NumberFormatException npe) {
                            }
                        }

                        String dateOut = null;
                        if( gtcwipStatus.getTestCompletionDate() != null )
                        {
                            dateOut =  gtcwipStatus.getTestCompletionDate();
                        }
                        else
                        {
                           Calendar cal = Calendar.getInstance();
                           dateOut =StringUtils.formatDateToString(cal.getTime());
                        }

                        if (quantityIn > 0 && quantityOut > 0 )
                        {
                            testLot.setLotNumber(lotNumber);
                            testLot.setPartNumber(partNumber);
                            testLot.setDateIn(gtcwipStatus.getReceivedDate());
                            testLot.setDateOut(dateOut);
                            testLot.setQtyIn(quantityIn + "");
                            testLot.setQtyOut(quantityOut + "");
                            testLot.setVendorName(VENDOR_NAME_GLOBAL_TEST);
                            testLot.setStatus(LOT_STATUS_CLOSE);
                            testLot.setPsType(LOCATION_TYPE_FT);
                            testLot.setCategory(LOT_CATEGORY_TYPE_PROD);
                            testLot.setDateCode(gtcwipStatus.getDateCode());
                            testLot.setFabLotNumber(lotNumber);
                            testLot.setPackageType(gtcwipStatus.getPackageType());
                            testLot.setTestProgramRevision(gtcwipStatus.getTestProgram());
                        }
                    }
                    else
                    {
                        testLot = (TestLot) m_ftDataMap.get(lotNumber + partNumber);

                        if (testLot == null)
                        {
                            testLot = new TestLot();
                            m_ftDataMap.put(lotNumber + partNumber, testLot);
                        }

                        int quantityIn = 0;
                        if (testLot.getQtyIn() != null)
                        {
                            try
                            {
                                quantityIn = Integer.parseInt(testLot.getQtyIn());
                            }
                            catch (NumberFormatException npe) {
                            }
                            try
                            {
                                quantityIn += Integer.parseInt( gtcwipStatus.getCurrentQty());
                            }
                            catch (NumberFormatException npe) {
                            }
                        }
                        else
                        {
                            try
                            {
                                quantityIn = Integer.parseInt( gtcwipStatus.getCurrentQty());
                            }
                            catch (NumberFormatException npe) {
                            }
                        }
                        if ( quantityIn > 0 )
                        {
                            testLot.setLotNumber(lotNumber);
                            testLot.setPartNumber(partNumber);
                            testLot.setDateIn(gtcwipStatus.getReceivedDate());
                            testLot.setQtyIn(quantityIn + "");
                            testLot.setVendorName(VENDOR_NAME_GLOBAL_TEST);
                            testLot.setStatus(LOT_STATUS_RUNNING);
                            testLot.setPsType(LOCATION_TYPE_FT);
                            testLot.setCategory(LOT_CATEGORY_TYPE_PROD);
                            testLot.setDateCode(gtcwipStatus.getDateCode());
                            testLot.setFabLotNumber(lotNumber);
                            testLot.setPackageType(gtcwipStatus.getPackageType());
                            testLot.setTestProgramRevision(gtcwipStatus.getTestProgram());
                        }
                    }
                }
                if (lotNumber != null && partNumber != null && gtcwipStatus.getStorage() != null)
                {
                    inventoryLot = (InventoryLot) m_invDataMap.get(lotNumber + partNumber);
                    if (inventoryLot == null)
                    {
                        inventoryLot = new InventoryLot(VENDOR_NAME_GLOBAL_TEST,LOCATION_TYPE_FG);
                        m_invDataMap.put(lotNumber + partNumber, inventoryLot);
                    }

                    int quantity = 0;
                    if ( inventoryLot.getQtyIn() != null )
                    {
                       try
                       {
                           quantity = Integer.parseInt( inventoryLot.getQtyIn() );
                       }
                       catch ( NumberFormatException ignore )
                       {
                       }
                       quantity += Integer.parseInt( gtcwipStatus.getStorage() );
                    }
                    else
                    {
                      quantity = Integer.parseInt( gtcwipStatus.getStorage() ) ;
                    }

                    inventoryLot.setPartNumber(partNumber);
                    inventoryLot.setLotNumber(lotNumber);
                    inventoryLot.setFabLotNumber(lotNumber);
                    inventoryLot.setQtyIn(quantity + "");
                    inventoryLot.setDateCode(gtcwipStatus.getDateCode());
                    inventoryLot.setDateIn(gtcwipStatus.getTestCompletionDate());
                    inventoryLot.setStatus(LOT_STATUS_RUNNING);
                    inventoryLot.setLotCategory(LOT_CATEGORY_TYPE_PROD);

                }
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
   
    private void log(String message)
    {
        if (message == null) return;

        if (m_parserLogger != null)
        {
            m_parserLogger.logDebug(message + LINE_SEPARATOR);
        }
        else
        {
            System.out.println(message);
        }
    }

}
